SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
1.6 KB · 46 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import Link from 'next/link';3import { notFound } from 'next/navigation';4import { LargestGrid, MonthStrip, TopEvents, TopLists } from '@/components/history/HistoryViews';5import { Section } from '@/components/ui/primitives';6import { apiGet } from '@/lib/api';7import type { HistorySummary } from '@/lib/types';89export const dynamic = 'force-dynamic';1011type Params = Promise<{ year: string }>;1213export async function generateMetadata({ params }: { params: Params }): Promise<Metadata> {14  const { year } = await params;15  return { title: `History ${year}`, description: `Global Internet Pressure in ${year}: months, largest events, most affected networks and regions.` };16}1718export default async function HistoryYearPage({ params }: { params: Params }) {19  const { year } = await params;20  if (!/^\d{4}$/.test(year)) notFound();21  const s = await apiGet<HistorySummary>(`/api/v1/history/summary?year=${year}`);22  return (23    <div className="pb-8">24      <header className="pt-6 pb-4">25        <p className="label">26          <Link href="/history" className="hover:text-ink">27            History28          </Link>{' '}29          · year30        </p>31        <h1 className="num mt-1 text-[26px] font-medium tracking-tight sm:text-[32px]">{year}</h1>32      </header>33      <Section label="Months">34        <MonthStrip months={s.months ?? []} />35      </Section>36      <Section label="Largest events">37        <LargestGrid largest={s.largest} />38      </Section>39      <TopLists s={s} />40      <Section label="Top events">41        <TopEvents events={s.top_events} />42      </Section>43    </div>44  );45}46